package com.bee.plus.ai.ali;

import com.alibaba.dashscope.aigc.generation.Generation;
import com.alibaba.dashscope.aigc.generation.GenerationParam;
import com.alibaba.dashscope.aigc.generation.GenerationResult;
import com.alibaba.dashscope.common.Message;
import com.alibaba.dashscope.utils.Constants;
import com.bee.plus.dto.ContentReq;
import com.bee.plus.dto.MessageReq;
import com.bee.plus.dto.MessageResp;
import com.bee.plus.ai.MessagePrepare;
import com.bee.plus.util.Conversation;
import com.bee.plus.util.ConversationThreadLocal;
import io.reactivex.Flowable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @author xupei
 */
@Service("aliyunAi")
public class AliyunAiServiceImpl extends MessagePrepare {


    @Autowired
    private AliyunAiManager aiManager;

    private static final Logger logger= LoggerFactory.getLogger(AliyunAiServiceImpl.class);

    @PostConstruct
    public void load(){
        Constants.apiKey=aiManager.getApiKey();

    }


    @Override
    protected MessageReq preprocessMessage(MessageReq messageReq){
        Conversation conversation=ConversationThreadLocal.getCurrentConversation();
        logger.info("conversationId {}",conversation.getConversationId());
        ContentReq contentReq=storeManger.getDb().getLastChatContentById(conversation.getConversationId());
         if(contentReq!=null){
             messageReq.getMessages().add(contentReq);
        }
        storeManger.getDb().storeChatInfo(messageReq.getMessages().get(0),conversation.getConversationId());

         Collections.reverse(messageReq.getMessages());
        return messageReq;
    }

    @Override
    protected MessageResp processMessage(MessageReq messageReq) {


        Generation gen = new Generation();
        List<Message> messages = new ArrayList<>();
        for(ContentReq contentReq:messageReq.getMessages()){
            Message message= Message.builder().role(contentReq.getRole()).content(contentReq.getContent()).build();
            messages.add(message);
        }
        logger.info("request params {}",messageReq.toString());
        GenerationParam param =
                GenerationParam.builder().model("qwen-turbo").messages(messages)
                        .resultFormat(GenerationParam.ResultFormat.MESSAGE)
                        .topP(0.8)
                        .build();
        try{
            GenerationResult result = gen.call(param);
            String content=result.getOutput().getChoices().get(0).getMessage().getContent();
            MessageResp messageResp= MessageResp.builder().content(content).role("system").build();

            return messageResp;
        }catch ( Exception e){
            e.printStackTrace();
            logger.error("aliyun chat {}",e.getLocalizedMessage());
        }



        return null;
    }

    @Override
    protected Flowable<MessageResp> processMessageStream(MessageReq messageReq) {
        Generation gen = new Generation();
        List<Message> messages = new ArrayList<>();
        for(ContentReq contentReq:messageReq.getMessages()){
            Message message= Message.builder().role(contentReq.getRole()).content(contentReq.getContent()).build();
            messages.add(message);
        }
       // logger.info("request params {}",messageReq.toString());
        GenerationParam param =
                GenerationParam.builder().model("qwen-turbo").messages(messages)
                        .resultFormat(GenerationParam.ResultFormat.MESSAGE)
                        .topP(0.8)
                        .build();
        try{
            Flowable<GenerationResult> result = gen.streamCall(param);

            return  Flowable.fromPublisher(result.map(generationResult -> {
                String content = generationResult.getOutput().getChoices().get(0).getMessage().getContent();
              //  logger.info("response-chat-params {} {}", Thread.currentThread().getId(), content);
                return MessageResp.builder().content(content).role("system").build();
            }).onErrorResumeNext(throwable -> {
                return Flowable.empty();
            }).doOnNext(messageResp -> {}));

        }catch ( Exception e){
            e.printStackTrace();
            logger.error("aliyun chat {}",e.getLocalizedMessage());
        }
        return null;
    }


    @Override
    public void storeChatMessage(MessageResp messageResp,Long conversationId) {
        super.postprocessResponse(messageResp,conversationId);
    }
}
